package com.qzxy.premiumhotelsystem.service.impl;

import cn.dev33.satoken.stp.SaLoginModel;
import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.qzxy.premiumhotelsystem.common.constant.UserRoleConstant;
import com.qzxy.premiumhotelsystem.domain.dto.GuestAndVipDTO;
import com.qzxy.premiumhotelsystem.domain.dto.GuestDTO;
import com.qzxy.premiumhotelsystem.domain.entity.Guests;
import com.qzxy.premiumhotelsystem.domain.vo.GuestInfoVo;
import com.qzxy.premiumhotelsystem.domain.vo.LoginVo;
import com.qzxy.premiumhotelsystem.mapper.GuestsMapper;
import com.qzxy.premiumhotelsystem.mapper.LogsMapper;
import com.qzxy.premiumhotelsystem.common.result.Result;
import com.qzxy.premiumhotelsystem.service.GuestsService;
import com.qzxy.premiumhotelsystem.utils.BaseContext;
import com.qzxy.premiumhotelsystem.utils.Bcrypt;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import jakarta.annotation.Resource;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;

import static com.qzxy.premiumhotelsystem.config.SaTokenConfig.guestStpLogic;
import static com.qzxy.premiumhotelsystem.common.result.ResultCodeEnum.PASSWORD_ERROR;
import static com.qzxy.premiumhotelsystem.common.result.ResultCodeEnum.USERNAME_ERROR;

/**
 * @author 14912
 * @description 针对表【guests】的数据库操作Service实现
 * @createDate 2024-09-12 15:55:14
 */
@Service
@Slf4j
public class GuestsServiceImpl extends ServiceImpl<GuestsMapper, Guests>
        implements GuestsService {

    @Resource
    private Bcrypt bcrypt;
    @Resource
    private GuestsMapper guestsMapper;
    @Resource
    private LogsMapper logsMapper;


    @Override
    public void deductMoney(String payPwd, BigDecimal price) {
        log.info("准备扣减余额,支付密码：{},价格：{}", payPwd, price);
        // 1.校验密码
        //TODO 暂时假设从这取，到时候等用户模块完善后看是从这还是redis
        String telephone = (String) StpUtil.getLoginId();
        Guests guestsFb = getByTelephone(telephone);
        Integer guestId = guestsFb.getGuestId();
        Guests guests = getById(guestId);
        if (guests == null) {
            // 用户不存在
            throw new RuntimeException("用户不存在");
        }
        if (!bcrypt.matches(payPwd, guests.getPayPwd())) {
            // 密码错误
            throw new RuntimeException("用户支付密码错误");
        }
        // 检查余额是否充足
        BigDecimal currentBalance = guests.getBalance();
        if (currentBalance.compareTo(price) < 0) {
            throw new RuntimeException("余额不足，无法支付");
        }

        // 2.尝试扣款
        //TODO 暂时假设从这取，到时候等用户模块完善后看是从这还是redis

        guests.setBalance(guests.getBalance().subtract(price));
        int updated = guestsMapper.updateById(guests);
        if (updated == 0) {
            throw new RuntimeException("扣款失败，可能是余额不足！");
        }
    }


    @Override
    public Guests getByTelephone(String telephone) {
        return guestsMapper.getByTelephone(telephone);
    }

    /**
     * 根据手机号删除用户
     *
     * @param telephone
     * @return
     */
    @Override
    public boolean deleteByTelephoneBoolean(String telephone) {
        return deleteByTelephoneBoolean(telephone);
    }

    @Override
    public Guests getByEmail(String email) {
        return guestsMapper.getByEmail(email);
    }


    /**
     * 查询所有顾客
     *
     * @return
     */
    @Override
    public List<Guests> allGuests() {
        return guestsMapper.allGuests();
    }

    /**
     * 用户登录方法
     *
     * @param loginVo
     * @return
     */
    @Override
    public String login(LoginVo loginVo) {
        return guestsMapper.login(loginVo);
    }

    @Override
    public boolean updateLoginStatus(String loginIp, String loginTime, String telephone) {
        return guestsMapper.updateLoginStatus(loginIp, loginTime, telephone);
    }

    @Override
    public boolean updateInformation(GuestInfoVo guestInfoVo) {
        boolean b = guestsMapper.updateInformation(guestInfoVo);
        String msg = b != false ? "更新用户基本信息成功" : "更新用户基本信息失败";
//        logsMapper.create(guestInfoVo.getTelephone(), msg);
        return b;
    }

    @Override
    public GuestAndVipDTO getVipType(String telephone) {
        return guestsMapper.getVipType(telephone);
    }

    /**
     * 分页查询用户
     *
     * @param pageSize
     * @param limit
     * @return
     */
    @Override
    public PageInfo<Guests> allGuestsForPage(Integer pageSize, Integer limit) {
        Page<Guests> page = PageHelper.startPage(pageSize, limit);
        List<Guests> guests = guestsMapper.allGuests();
        return page.toPageInfo();
    }


    /**
     * 更新用户全部信息
     *
     * @param guests
     * @return
     */
    @Override
    public boolean updateAllInformation(Guests guests) {
        return guestsMapper.updateAllInformation(guests);
    }

    /**
     * 头像上传
     * @param url
     * @param telephone
     * @return
     */
    @Override
    public boolean uploadAvatar(String url, String telephone) {
        return guestsMapper.uploadAvatar(url,telephone);
    }


    @Override
    public void repairBalance(Integer guestId, BigDecimal actuallyPrice) {
        Guests guests = getById(guestId);
        if (guests == null) {
            // 用户不存在
            throw new RuntimeException("用户不存在");
        }
        guests.setBalance(guests.getBalance().add(actuallyPrice));
        int updated = guestsMapper.updateById(guests);
        if (updated == 0) {
            throw new RuntimeException("余额恢复失败，系统异常！");
        }
    }
    @Override
    public List<GuestDTO> guestsForOrderStatusAll() {
        return guestsMapper.guestsForOrderStatusAll();
    }

    @Override
    public List<GuestDTO> guestsForOrderStatus() {
        return guestsMapper.guestsForOrderStatus();
    }

    @Override
    public List<GuestDTO> guestsForOrderStatusHistory() {
        return guestsMapper.guestsForOrderStatusHistory();
    }
}




